# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs -run-pass=si-fold-operands  %s -o - | FileCheck -check-prefix=GCN %s

--- |
  define amdgpu_kernel void @redef_m0_same_copy() { ret void }
  define amdgpu_kernel void @multi_redef_m0_same_copy() { ret void }
  define amdgpu_kernel void @redef_m0_different_copy() { ret void }
  define amdgpu_kernel void @redef_m0_mixed_copy0() { ret void }
  define amdgpu_kernel void @redef_m0_mixed_copy1() { ret void }
  define amdgpu_kernel void @redef_m0_same_mov_imm() { ret void }
  define amdgpu_kernel void @redef_m0_different_inst0() { ret void }
  define amdgpu_kernel void @redef_m0_different_inst1() { ret void }
  define amdgpu_kernel void @redef_m0_mixed_read_m0() { ret void }
  define amdgpu_kernel void @redef_m0_same_copy_call() { ret void }
  define amdgpu_kernel void @redef_m0_same_copy_multi_block() { ret void }
  define amdgpu_kernel void @redef_m0_copy_self() { ret void }
  define amdgpu_kernel void @redef_m0_copy_physreg() { ret void }

  declare void @func()
...

---
name:            redef_m0_same_copy
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_same_copy
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            multi_redef_m0_same_copy
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: multi_redef_m0_same_copy
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %1
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_different_copy
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0, $sgpr1

    ; GCN-LABEL: name: redef_m0_different_copy
    ; GCN: liveins: $vgpr0, $sgpr0, $sgpr1
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = COPY [[COPY2]]
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    %2:sgpr_32 = COPY $sgpr1
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %2
    %4:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_mixed_copy0
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0, $sgpr1

    ; GCN-LABEL: name: redef_m0_mixed_copy0
    ; GCN: liveins: $vgpr0, $sgpr0, $sgpr1
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = COPY [[COPY2]]
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    %2:sgpr_32 = COPY $sgpr1
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %1
    $m0 = COPY %2
    %4:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_mixed_copy1
tracksRegLiveness: true

machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0, $sgpr1

    ; GCN-LABEL: name: redef_m0_mixed_copy1
    ; GCN: liveins: $vgpr0, $sgpr0, $sgpr1
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = COPY [[COPY2]]
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    %2:sgpr_32 = COPY $sgpr1
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %2
    $m0 = COPY %1
    %4:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_same_mov_imm
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_same_mov_imm
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = S_MOV_B32 -1
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = S_MOV_B32 -1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = S_MOV_B32 -1
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_different_inst0
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_different_inst0
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = IMPLICIT_DEF
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = IMPLICIT_DEF
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_different_inst1
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_different_inst1
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: S_NOP 0, implicit-def $m0
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    S_NOP 0, implicit-def $m0
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_mixed_read_m0
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0, $sgpr1

    ; GCN-LABEL: name: redef_m0_mixed_read_m0
    ; GCN: liveins: $vgpr0, $sgpr0, $sgpr1
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = COPY [[COPY2]]
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: [[DS_READ_B32_2:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 128, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    %2:sgpr_32 = COPY $sgpr1
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %2
    %4:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY %2
    %5:vgpr_32 = DS_READ_B32 %0, 128, 0, implicit $m0, implicit $exec :: (load (s32))
...

---
name:            redef_m0_same_copy_call
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_same_copy_call
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: dead $sgpr30_sgpr31 = SI_CALL undef $sgpr6_sgpr7, @func, csr_amdgpu
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    dead $sgpr30_sgpr31 = SI_CALL undef $sgpr6_sgpr7, @func, csr_amdgpu
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_same_copy_multi_block
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  ; GCN-LABEL: name: redef_m0_same_copy_multi_block
  ; GCN: bb.0:
  ; GCN-NEXT:   successors: %bb.1(0x80000000)
  ; GCN-NEXT:   liveins: $vgpr0, $sgpr0
  ; GCN-NEXT: {{  $}}
  ; GCN-NEXT:   [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
  ; GCN-NEXT:   [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
  ; GCN-NEXT:   $m0 = COPY [[COPY1]]
  ; GCN-NEXT:   [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
  ; GCN-NEXT: {{  $}}
  ; GCN-NEXT: bb.1:
  ; GCN-NEXT:   $m0 = COPY [[COPY1]]
  ; GCN-NEXT:   [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
  bb.0:
    liveins: $vgpr0, $sgpr0

    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))

  bb.1:
    $m0 = COPY %1
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_copy_self
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_copy_self
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY [[COPY1]]
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $m0 = COPY $m0
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY %1
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $m0 = COPY $m0
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...

---
name:            redef_m0_copy_physreg
tracksRegLiveness: true
machineFunctionInfo:
  isEntryFunction: true
body:             |
  bb.0:
    liveins: $vgpr0, $sgpr0

    ; GCN-LABEL: name: redef_m0_copy_physreg
    ; GCN: liveins: $vgpr0, $sgpr0
    ; GCN-NEXT: {{  $}}
    ; GCN-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
    ; GCN-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
    ; GCN-NEXT: $m0 = COPY $sgpr0
    ; GCN-NEXT: [[DS_READ_B32_:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 0, 0, implicit $m0, implicit $exec :: (load (s32))
    ; GCN-NEXT: $sgpr0 = S_MOV_B32 0
    ; GCN-NEXT: $m0 = COPY $sgpr0
    ; GCN-NEXT: [[DS_READ_B32_1:%[0-9]+]]:vgpr_32 = DS_READ_B32 [[COPY]], 64, 0, implicit $m0, implicit $exec :: (load (s32))
    %0:vgpr_32 = COPY $vgpr0
    %1:sgpr_32 = COPY $sgpr0
    $m0 = COPY $sgpr0
    %2:vgpr_32 = DS_READ_B32 %0, 0, 0, implicit $m0, implicit $exec :: (load (s32))
    $sgpr0 = S_MOV_B32 0
    $m0 = COPY $sgpr0
    %3:vgpr_32 = DS_READ_B32 %0, 64, 0, implicit $m0, implicit $exec :: (load (s32))

...
